package com.geline.sqlbackup.druid;

import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddConstraint;
import com.alibaba.druid.sql.ast.statement.SQLCommentStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor;
import com.alibaba.druid.sql.parser.ParserException;
import com.alibaba.druid.sql.parser.SQLParserUtils;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
import com.alibaba.druid.util.JdbcConstants;
import com.geline.sqlbackup.bean.ColumnInfo;
import com.geline.sqlbackup.bean.TableColumnInfo;
import com.geline.sqlbackup.thirdjar.OracleType;
import com.geline.sqlbackup.util.JavaPackageKit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * @author mengx
 * @date 2020/12/27 10:28
 */
public class OracleDdlSqlHandler implements DdlSqlHandler {
    private static final Logger log = LoggerFactory.getLogger(OracleDdlSqlHandler.class);

    @Override
    public TableColumnInfo handler(String ddlSql, List<String> ignoredColumnList, boolean useRemoveTableHead, boolean useCamelCase) {
        TableColumnInfo tableColumnInfo = new TableColumnInfo();

        List<ColumnInfo> columnInfoList = new ArrayList<>();
        SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(ddlSql, JdbcConstants.ORACLE);

        List<SQLStatement> sqlStatementList = parser.parseStatementList();
        for (SQLStatement sqlStatement : sqlStatementList){
            if (sqlStatement instanceof SQLCreateTableStatement) {
                SQLCreateTableStatement createTableStatement = (SQLCreateTableStatement) sqlStatement;
                //解析字段信息 create table 语句
                columnInfoList = initColumnInfoList(createTableStatement, ignoredColumnList, useCamelCase);

                //解析表名
                String tableName = createTableStatement.getTableName();
                tableName = tableName.replaceAll("\"|'|`", "").trim();
                tableColumnInfo.setTableName(tableName);

                //解析表注释
                SQLExpr comment = createTableStatement.getComment();
                String tableComment = comment==null ? "" : ((SQLCharExpr)comment).getText();
                tableColumnInfo.setTableComment(tableComment);

                //设置entity名
                String entityName = JavaPackageKit.getTableEntityName(useRemoveTableHead, useCamelCase, tableName);
                tableColumnInfo.setEntityName(entityName);
            }else if(sqlStatement instanceof SQLCommentStatement){
                ////delete////解析 COMMENT ON COLUMN 语句
                /*SQLCommentStatement cstmt = (SQLCommentStatement) sqlStatement;
                // COMMENT ON COLUMN "JEECGBOOT"."CES_ORDER_CUSTOMER"."CREATE_BY" IS '创建人';
                String lineStr = cstmt.toString();
                lineStr = lineStr.replaceAll(";", "");
                lineStr = lineStr.replaceAll("(?i)COMMENT ON COLUMN", "");
                lineStr = lineStr.replaceAll("IS "+cstmt.getComment().toString(), "");
                lineStr = lineStr.replaceAll("\"|'|`", "");
                String name = lineStr.indexOf(".") > 0 ? lineStr.substring(lineStr.lastIndexOf(".")+1).trim() : lineStr.trim();
                String comment = cstmt.getComment().toString().replaceAll("\"|'|`", "");
                nameCommentMap.put(name, comment);*/
                log.warn(".....SQLCommentStatement.... "+sqlStatement);
            }else if(sqlStatement instanceof SQLAlterTableAddConstraint){
                // alter table ECS_STORE.TF_B_AIR_CONFIG add constraint TF_B_AIR_CONFIG_PK primary key (TYPE_ID);
                /*SQLAlterTableAddConstraint cstmt = (SQLAlterTableAddConstraint) sqlStatement;
                SQLConstraint constraint = cstmt.getConstraint();
                SQLName name = constraint.getName();*/
                log.warn(".....SQLAlterTableAddConstraint.... "+sqlStatement);
            }
        }

        tableColumnInfo.setColumnInfoList(columnInfoList);
        tableColumnInfo.setDbType(DbType.oracle.name());
        return tableColumnInfo;
    }

    @Override
    public SchemaStatVisitor initSchemaStatVisitor() {
        return new OracleSchemaStatVisitor();
    }

    @Override
    public Integer getVendorTypeNumber(String columnName, String dataType) {
        OracleType dbType = null;
        try {
            dbType = OracleType.valueOf(dataType.toUpperCase());
        }catch (Exception e){
            log.error(e.getMessage());
        }
        if(null == dbType){
            String msg = String.format("Invalid field type in Oracle ! %s [%s]", columnName, dataType);
            log.warn(msg);
            throw new ParserException(msg);
        }
        return dbType.getVendorTypeNumber();
    }

    @Override
    public String getJavaType(String columnName, String dataType) {
        return null;
    }

}
